package http_codec

type Serializer interface {
	// Unmarshal deserialize the in bytes into body
	Unmarshal(in []byte, body interface{}) error

	// Marshal returns the bytes serialized from body.
	Marshal(body interface{}) (out []byte, err error)
}

var serializers = make(map[int]Serializer)

const (
	// SerializationTypePB is protobuf serialization code.
	SerializationTypePB = 1 << iota
	// SerializationTypeJCE is jce serialization code.
	SerializationTypeJCE
	// SerializationTypeJSON is json serialization code.
	SerializationTypeJSON
	// SerializationTypeFlatBuffer is flatbuffer serialization code.
	SerializationTypeFlatBuffer
	// SerializationTypeNoop is bytes empty serialization code.
	SerializationTypeNoop
	// SerializationTypeXML is xml serialization code (application/xml for http).
	SerializationTypeXML
	// SerializationTypeTextXML is xml serialization code (text/xml for http).
	SerializationTypeTextXML
	// SerializationTypeUnsupported is unsupported serialization code.
	SerializationTypeUnsupported
	// SerializationTypeForm is used to handle form request.
	SerializationTypeForm
	// SerializationTypeGet is used to handle http get request.
	SerializationTypeGet
	// SerializationTypeFormData is used to handle form data.
	SerializationTypeFormData
)

var ContentTypeSerializationType = map[string]int{
	"get/url":                           0,
	"application/json":                  SerializationTypeJSON,
	"application/protobuf":              SerializationTypePB,
	"application/x-protobuf":            SerializationTypePB,
	"application/pb":                    SerializationTypePB,
	"application/proto":                 SerializationTypePB,
	"application/jce":                   SerializationTypeJCE,
	"application/flatbuffer":            SerializationTypeFlatBuffer,
	"application/octet-stream":          SerializationTypeNoop,
	"application/x-www-form-urlencoded": SerializationTypeForm,
	"application/xml":                   SerializationTypeXML,
	"text/xml":                          SerializationTypeTextXML,
	"multipart/form-data":               SerializationTypeFormData,
}

var SerializationTypeContentType = map[int]string{
	0:                           "get/url",
	SerializationTypeJSON:       "application/json",
	SerializationTypePB:         "application/proto",
	SerializationTypeJCE:        "application/jce",
	SerializationTypeFlatBuffer: "application/flatbuffer",
	SerializationTypeNoop:       "application/octet-stream",
	SerializationTypeForm:       "application/x-www-form-urlencoded",
	SerializationTypeXML:        "application/xml",
	SerializationTypeTextXML:    "text/xml",
	SerializationTypeFormData:   "multipart/form-data",
}

func RegisterHttpSerializer(contentType string, s Serializer) {
	sType, ok := ContentTypeSerializationType[contentType]
	if !ok {
		//全新的未注册的content type，需要做的操作是在map内找到最大数字然后+1
		m := 0
		for _, v := range ContentTypeSerializationType {
			if v > m {
				m = v
			}
		}
		for k, _ := range SerializationTypeContentType {
			if k > m {
				m = k
			}
		}
		m++
		ContentTypeSerializationType[contentType] = m
		SerializationTypeContentType[m] = contentType
	}
	serializers[sType] = s
}

func HttpSerializerMarshal(sType int, body interface{}) ([]byte, error) {
	return serializers[sType].Marshal(body)
}

func HttpSerializerUnMarshal(sType int, bytes []byte, body interface{}) error {
	return serializers[sType].Unmarshal(bytes, body)
}
